﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Xml;
using EpiInfoCloudMagpiBridge.Models;
using Ewav.Security;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace EpiInfoCloudMagpiBridge.Controllers
{
    /// <summary>
    ///  THIS CODE ASSUMES ONE SERVICE PER USER!!!!!     
    /// </summary>
    [Authorize]
    public class DownloadResponseController : Controller
    {

        private const string _ewavAzureServiceDirective = "tables/";
        private readonly string _baseAddressMagpiServer_Data =
            ConfigurationManager.AppSettings["baseAddressMagpiServer_Data"];
        private string _baseAddressMagpiEwavMobileService = "  ";
        private MagpiEWAVEntities _context;
        private Cryptography _cy;
        private string _ewavAzureServiceTableName = ""; //      ; "step500gb"; //Sachin:from db
        private long _recordsTransferred;

        private string _getMagpiEwavMobileServiceName()
        {
            string magpiEwavMobileServiceName = "";

            _cy = new Cryptography();
            _context = new MagpiEWAVEntities(_cy.Decrypt(ConfigurationManager.ConnectionStrings["MagpiEWAVEntities"].ToString()));

            if (HelperFunctions.UserHasAzureServices())
            {
                magpiEwavMobileServiceName = _context.AzureMobileServiceSettings.Where(
                    z => z.EWAVUserID == ApplicationModel.CurrentEwavUserId).ToList()[0].MobileServiceName;
            }

            return magpiEwavMobileServiceName;
        }


        [HttpGet]
        public ActionResult Index()
        {
            _cy = new Cryptography();
            _context =
                new MagpiEWAVEntities(_cy.Decrypt(ConfigurationManager.ConnectionStrings["MagpiEWAVEntities"].ToString()));

            _baseAddressMagpiEwavMobileService = "https://" + _getMagpiEwavMobileServiceName() +
                                                 ".azure-mobile.net/";

            List<MagpiAzureMapping> magpiAzureMappingList =
                _context.MagpiAzureMappings.Where(
                    x => x.EWAVUserID == ApplicationModel.CurrentEwavUserId).ToList();

            DownloadResponsesHelper drh = new DownloadResponsesHelper();
            drh.MagpiAzureMappingList = magpiAzureMappingList;
            drh.DownloadCompleteText = "";

            return View(drh);
        }

        public ActionResult Download()
        {
            _baseAddressMagpiEwavMobileService = "https://" + _getMagpiEwavMobileServiceName() +
                                                 ".azure-mobile.net/";
            // Get data from form  
            string sDate_fromForm = Request.Form["startDate"];
            string eDate_fromFrom = Request.Form["endDate"];
            string surveyID_fromForm = Request.Form["dropdown-2"];

            // Format date for Magpi API        
            DateTime startDate = new DateTime();
            DateTime.TryParse(sDate_fromForm, out startDate);
            DateTime endDate = new DateTime();
            DateTime.TryParse(eDate_fromFrom, out endDate);

            sDate_fromForm = startDate.Year + "-" + startDate.Month + "-" + startDate.Day;
            eDate_fromFrom = endDate.Year + "-" + endDate.Month + "-" + endDate.Day;

            _cy = new Cryptography();
            _context =
                new MagpiEWAVEntities(_cy.Decrypt(ConfigurationManager.ConnectionStrings["MagpiEWAVEntities"].ToString()));

            //  Get user's credentials        
            MagpiAccountSetting magpiAccountSetting =
                _context.MagpiAccountSettings.Where(m => m.EWAVUserID == ApplicationModel.CurrentEwavUserId).ToList()[0];
            MagpiAzureMapping magpiAzureMapping =
                _context.MagpiAzureMappings.Where(az => az.SurveyID == surveyID_fromForm).ToList()[0];

            _ewavAzureServiceTableName = magpiAzureMapping.MobileServiceTableName;

            // Create theh Magpi query    
            var magpiUriBuilder = new UriBuilder(_baseAddressMagpiServer_Data);
            var query = HttpUtility.ParseQueryString("");

            query["username"] = magpiAccountSetting.MagpiUsername; //   _magpiUsername;
            query["accesstoken"] = magpiAccountSetting.MagpiAccessToken; //   _magpiAccesstoken;          
            query["surveyid"] = surveyID_fromForm; //   _magpiSurveyid;
            query["startDate"] = sDate_fromForm;
            query["endDate"] = eDate_fromFrom;

            magpiUriBuilder.Query = query.ToString().Replace("++", "");

            // Retrieve XML from MagPi service  
            XmlDocument xDoc = HelperFunctions.getMagpiXml(magpiUriBuilder.Uri.ToString());

            // Convert Xml to Json    
            string json = JsonConvert.SerializeXmlNode(xDoc);

            // Post Json to Azure           
            _postJsonToAzure(json);

            List<MagpiAzureMapping> magpiAzureMappingList =
                _context.MagpiAzureMappings.Where(
                    x => x.EWAVUserID == ApplicationModel.CurrentEwavUserId).ToList();

            DownloadResponsesHelper drh = new DownloadResponsesHelper();
            drh.MagpiAzureMappingList = magpiAzureMappingList;
            drh.DownloadCompleteText =
                string.Format(
                    "Transfer of {0} records from survey {1}, dates {2} to {3} from Magpi to Azure is complete",
                    _recordsTransferred, surveyID_fromForm.Trim(), sDate_fromForm, eDate_fromFrom);

            return View("Index", drh);
        }

        /// <summary>
        ///  Parse JSON from  XmlDocument     
        /// </summary>
        /// <param name="json"></param>
        private void _postJsonToAzure(string json)
        {
            //  Strip away the outer shells     
            JObject outer = JObject.Parse(json);
            JObject children = outer["SurveyDataList"] as JObject;

            if (children != null)
            {
                JArray children2 = children["SurveyData"] as JArray;
                string jsonForAzure = "";

                if (children2 != null)
                {
                    foreach (var jToken in children2)
                    {
                        var jObject = (JObject)jToken;
                        //  "Id" field must be removed for Azure compatihility                   
                        jObject.Remove("Id"); //
                        jsonForAzure = jObject.ToString();
                        // Check if UserId already exists 
                        if (_recordExists(jObject["uuid"].ToString()) == false)
                        {
                            _doAzurePost(jsonForAzure);
                            _recordsTransferred++;
                        }
                    }
                }
            }
        }

        private bool _recordExists(string uuid)
        {
            // Set up Uri     
            UriBuilder ewavAzureUriBuilder = new UriBuilder(_baseAddressMagpiEwavMobileService);
            ewavAzureUriBuilder.Path += _ewavAzureServiceDirective;
            ewavAzureUriBuilder.Path += _ewavAzureServiceTableName;
            ewavAzureUriBuilder.Path += string.Format("?$filter=(uuid eq {0})", "'" + Server.HtmlEncode(uuid) + "'");

            _cy = new Cryptography();
            _context =
                new MagpiEWAVEntities(_cy.Decrypt(ConfigurationManager.ConnectionStrings["MagpiEWAVEntities"].ToString()));

            //  Get user's credentials        
            AzureMobileServiceSetting azureMobileServiceSetting =
                _context.AzureMobileServiceSettings.Where(
                    m => m.EWAVUserID == ApplicationModel.CurrentEwavUserId).ToList()[0];

            // Set up Http Request      
            var http = (HttpWebRequest)WebRequest.Create(ewavAzureUriBuilder.Uri);
            http.Accept = "application/json";
            http.ContentType = "application/json";
            http.Headers.Add("X-ZUMO-APPLICATION", azureMobileServiceSetting.ApplicationKey);
            //Sachin:this key can come from database
            http.Method = "GET";

            // Get response     
            var response = http.GetResponse();

            // Read response  
            var stream = response.GetResponseStream();
            var sr = new StreamReader(stream);
            var content = sr.ReadToEnd();

            // If response is empty Json return false else true    
            if (content == "[]")
                return false;
            return true;
        }

        /// <summary>
        ///     Post Json to the EwavAzure mohile service
        /// </summary>
        /// <param name="jsonForAzure"></param>
        private void _doAzurePost(string jsonForAzure)
        {
            // Set up Uri  
            UriBuilder ewavAzureUriBuilder = new UriBuilder(_baseAddressMagpiEwavMobileService);
            ewavAzureUriBuilder.Path += _ewavAzureServiceDirective;
            ewavAzureUriBuilder.Path += _ewavAzureServiceTableName;

            _cy = new Cryptography();
            _context =
                new MagpiEWAVEntities(_cy.Decrypt(ConfigurationManager.ConnectionStrings["MagpiEWAVEntities"].ToString()));

            //  Get user's credentials        
            AzureMobileServiceSetting azureMobileServiceSetting =
                _context.AzureMobileServiceSettings.Where(
                    m => m.EWAVUserID == ApplicationModel.CurrentEwavUserId).ToList()[0];

            // Set up Http request    
            var http = (HttpWebRequest)WebRequest.Create(ewavAzureUriBuilder.Uri);
            http.Accept = "application/json";
            http.ContentType = "application/json";
            http.Headers.Add("X-ZUMO-APPLICATION", azureMobileServiceSetting.ApplicationKey); //Sachin:from db
            http.Method = "POST";

            // Create the request body    
            ASCIIEncoding encoding = new ASCIIEncoding();
            byte[] bytes = encoding.GetBytes(jsonForAzure);

            //  Add the content to post to the request body        
            Stream newStream = http.GetRequestStream();
            newStream.Write(bytes, 0, bytes.Length);
            newStream.Close();

            // Get the response         
            var response = http.GetResponse();

            // Capture content     
            var stream = response.GetResponseStream();
            var sr = new StreamReader(stream);
            var content = sr.ReadToEnd();
        }
    }
}